california

Introduction

Our goal for this porject was to create interesting visualization showing correlations between causes of death and the demographic trends in the zip codes of California.

In order to do so we are cleaning dirty Zip code data from the US Census and as well as zip code data corresponding to cause of death. These data sets are available on data.world. These data sets are joined using Tableau and R, with which we can produce the visualizations we present in this document.

The following links refer to the census data used for out visualizations.

Median Income data was taken from the following link to the US Census Data in data.world: https://data.world/uscensusbureau/acs-2015-5-e-income

Median Age data was taken from the following link to the US Census Data in data.world: https://data.world/uscensusbureau/acs-2015-5-e-agesex

Dominant Race data was taken from the following link to the US Census Data in data.world: https://data.world/uscensusbureau/acs-2015-5-e-race

R Configuration

Below we display our sessionInfo().

sessionInfo(package=NULL)
R version 3.3.2 (2016-10-31)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 7 x64 (build 7601) Service Pack 1

locale:
[1] LC_COLLATE=English_United States.1252  LC_CTYPE=English_United States.1252   
[3] LC_MONETARY=English_United States.1252 LC_NUMERIC=C                          
[5] LC_TIME=English_United States.1252    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
 [1] plyr_1.8.4           RCurl_1.95-4.8       bitops_1.0-6         jsonlite_1.3        
 [5] plotly_4.6.0         leaflet_1.1.0        lubridate_1.6.0      DT_0.2              
 [9] readr_1.1.0          data.world_0.1.2     dplyr_0.5.0          ggplot2_2.2.1       
[13] shinydashboard_0.5.3 shiny_1.0.0         

loaded via a namespace (and not attached):
 [1] Rcpp_0.12.10      base64enc_0.1-3   tools_3.3.2       digest_0.6.11     viridisLite_0.2.0
 [6] evaluate_0.10     tibble_1.3.0      gtable_0.2.0      DBI_0.5-1         crosstalk_1.0.0  
[11] curl_2.4          yaml_2.1.14       stringr_1.1.0     httr_1.2.1        knitr_1.15.1     
[16] sourcetools_0.1.5 htmlwidgets_0.8   hms_0.3           rprojroot_1.2     grid_3.3.2       
[21] R6_2.2.0          rmarkdown_1.3     tidyr_0.6.1       purrr_0.2.2       magrittr_1.5     
[26] backports_1.0.5   scales_0.4.1      htmltools_0.3.5   rsconnect_0.7     assertthat_0.1   
[31] mime_0.5          xtable_1.8-2      colorspace_1.3-2  httpuv_1.3.3      labeling_0.3     
[36] stringi_1.1.2     lazyeval_0.2.0    munsell_0.4.3    

Data Summary

The follwoing heads and summaries demonstrate the data that will be joined via data.world in our queries when using shiny. This data will also be joined in tableau for the corresponding visualizations.

    ZipCode                 Dominant    
 10001  :    1   American_Indian:  366  
 10002  :    1   Asian          :  138  
 10003  :    1   Black          : 1486  
 10004  :    1   Native_Hawaiian:   12  
 10005  :    1   Other          :  106  
 10006  :    1   White          :30881  
 (Other):32983                          
      Year         ZIP Code     Causes of Death        Count           Location        
 Min.   :1999   Min.   :90001   Length:320152      Min.   :   0.00   Length:320152     
 1st Qu.:2002   1st Qu.:92126   Class :character   1st Qu.:   0.00   Class :character  
 Median :2006   Median :93535   Mode  :character   Median :   3.00   Mode  :character  
 Mean   :2006   Mean   :93514                      Mean   :  11.01                     
 3rd Qu.:2010   3rd Qu.:95254                      3rd Qu.:  10.00                     
 Max.   :2013   Max.   :99999                      Max.   :1003.00                     

Processing the Data

The csv files containing our data of interest were passed through individual ETL files for cleaning. In this process spaces are included between upper and lower cased letters and ampersands are changed to the word “and”.These subtleties among others are done to effectively upload the data files to data.world. Because our data did not require much “cleaning” or renaming of columns, we did not need to include in depth code in the ETL file. We used many “cookie-cutter” ETL files to clean the many files we used for our joins. These files include “ETL_median_age.R, ETL_dominant_race.R, ETL_median_income.R, ETL_export1.R, ETL_export2.R, and ETL_export3.R.” Below is a source or link to one of our ETL files.

Below is a source of our etl file used to clean our dominant race file,

Parsed with column specification:
cols(
  ZipCode = col_integer(),
  Dominant = col_character()
)

The following screen shot shows some of the code used to clean the dominant race file.

knitr::include_graphics("../01Data/dominantRace.png")

Tableau Visualizations Steps

Retrieving our Data

We pulled in 3 grouped data sets from our project that originated from the US Census (Median_Income_Raw.csv, and Median_Age_Raw.csv). In addition, we grouped a set from race deomgraphics Census data to create the domianat_race.csv. In order to create this file, we queried the orginal census data in a way we could define the domianant race in each zip code.A new column was added to the data set indicating the most represented race in each zip code. We used the data.world connector to retrieve everything from our final project site on data.world. This is where we also pulled the Cause of Death data set. These files were inner joined on ZIP Code to analyze cause and count of death to median income, dominant race, and median age in each ZIP Code.

knitr::include_graphics("../03Visualizations/join.png")

Boxplot Visualization Steps

Step 1 - Boxplot Overview

In order to create our box plot we set causes of death as the columns which can be seen along the x-axis of the plot. The row are set as the count of deaths as seen on the y-axis of the plot. Each zip code has a corresponding point on the boxplot for each cause of death. We set dominant race as the color of the points in the plot. Therefore, the color of each point depends on each zip code’s dominant race. The boxes along each column mark the 25th to 75th percentile of counts of deaths per zip code for each cause. The whiskers mark the highest and lowest count values considered to not be outliers.

Step 2 - Filter

We added a filter to this boxplot in order to define the range of the median incomes of the zipcodes displyed.

knitr::include_graphics("../03Visualizations/Boxplot1.png")

knitr::include_graphics("../03Visualizations/Boxplot2.png")

knitr::include_graphics("../03Visualizations/Boxplot3.png")

knitr::include_graphics("../03Visualizations/Boxplot4.png")

knitr::include_graphics("../03Visualizations/Boxplot5.png")

knitr::include_graphics(“../03Visualizations/Tableau_Screenshots/Boxplot3.png”)

income

Histogram Visualization Steps

Step 1 - Histogram Overview

For this plot we set our column as median household income and columns to count of people in the corresponding income. Therefore, each bar represents the count of people living in zip codes binned to corresponding median incomes. In addition, dominant race was added as a color to represent the count of people in that binned median income of zip codes of each dominant race.

Step 2 - Filter

For this plot race was set as a filter. The user can then filter which dominant race zip codes should be displayed in the binned population count.

knitr::include_graphics("../03Visualizations/Tableau_Screenshots/2.png")

Scatter Plot Visualization Steps

Step 1 -Scatter Plot Overview

In order to create our scatter plot we set our columns as our zip code median age and the rows as the count of deaths. Each point represents the count of deaths in a particular zip code. Color was added to these points to represent the dominant race in each zip code.

Step 2 -Pages

Pages were added to the visualization with respect to cause of death. Each page then only shows the count of deaths due to a specific cause for each zip code.

Step 3 -Scatter Plot Map

Based on this data a map was created in a separate sheet. Points in the state of California correspond to the zip codes sampled. The size of the points correspond to the median income of each zip code.The color of each point corresponds to the most represented race in each zip code.

Step 4 -Zip Code Lines Map

In addition, another map was reproduced in a different sheet dividing the state of california by zip code lines. Death count is represented as the color of the area of each zip code. A filter was created to only display zip codes with a the chosen range of deaths. From this map we note that the zip code with most deaths due to cancer is located in NAPA valley. This location is known for mass farming. We would be intrested in knowing if pesticides used in the area could account for the highest cancer rates seen in the state of California.

Step 3 -Actions

Both maps produced were set as a target sheets which can filter to only show zip codes displayed in the chosen page in the scatter plot sheet. Therefore, only zip codes affected by a certain cause of deaths will be displayed in the map if the corresponding cause is the selected page.

knitr::include_graphics("../03Visualizations/Tableau_Screenshots/3.png")

knitr::include_graphics("../03Visualizations/Tableau_Screenshots/5.png")

Crosstab Visualization Steps

Step 1 - Crosstab Overview

In order to create our crosstab we set race as our columns and cause of death as our rows. Text then was added in the cells as count of deaths pertaining to the cell. Each cell then contains the count of deaths for zip codes with a certain dominant race due to a certain cause. The color of the text as set as our KPI which is decribed in the next step.

Step 2 - Calculated field: Average deaths per zip code

For our key preformance indicator we chose to divide the count found in the crosstab cells by the number of zipcodes accounting for the count. This give the averge count of deaths due to a certain cause per zip code of a certain dominant race. The color of the text in each cell corresponds to the avergae deaths per zip code in that cell.

knitr::include_graphics("../03Visualizations/Tableau_Screenshots/6.png")

Barchart Visualization Steps

Step 1 - Barchart Overview

We created barcharts between median age (one blue) and cause of death (second blue) in the columns slot. This then lists all the causes of death and within each cause of death lists the median age bins we created The KPI- average deaths per zip code (green) was added as the row of the barcharts. With this average count we can compare the average number of people dying per zip code of a certain cause of death across zip codes of different median ages. This was done cosidering that certain median incomes were over represented in our data. Therefore the bars of our barchart represent the average count of deaths perzip code due to a certain cause in zip codes of a certain median income.

Step 2 - Calculated Field: Average deaths per zip code

As mentioned, the calculated field used was average deaths per zip code. This takes the count of deaths and divides it by the number of zip codes represented.

Step 3 - Reference Line

The parameter represented by reference lines takes the average of the averages of deaths per zip code across different median incomes due to the same cause of death. Therefore, one reference line is assigned to each cause of death to represent this parameter.

Step 4 - Table Calculations

The table calculation takes the calculated average used as the parameter for our refernce line and subtracts this number from the average counts in each bar(resulting in a difference for each median income). This calculation is refered to as the difference from the average.

knitr::include_graphics("../03Visualizations/Tableau_Screenshots/7.png")

knitr::include_graphics("../03Visualizations/Tableau_Screenshots/8.png")

knitr::include_graphics("../03Visualizations/Tableau_Screenshots/9.png")

Shiny Visualization Steps

Link: https://anandpant.shinyapps.io/project_final/

The shiny app creates plots using queries set to bring in data of interest from data.world. In these queries Census data is joined to the causes of death files. This is created with an inner join on the zip code in both files. The SQL to join is found in the server code for our shiny aplication.

The user should click on the get data button. This button sends a SQL query to data.world to join and bring in the data set mentioned above.

The returned data set will be used by ggplot code to create the different visualizations shown below.

Step 1

Navigate to 02 Shiny and open Server.R

Step 2

Click publish.

Step 3

Choose either age, race, or income in the sidebar menu.

Step 4

Select get data. The barchart will be created. You can view the barchart by clicking barchart tab.

Shiny Visualizations

Shiny - Data Tab

The image below shows the data tab panel. This is found in ever tab in our application. It displays the data we use in our visualization in a tabulated format. This data is the data we query from data.world which is queried upon selecting the get data button.

** Boxplot Tab** In order to create our box plot we set causes of death as the x-axis of the plot. The y axis is set as the count of deaths. Each set of zip code for each dominant race has a corresponding box and whisker plot for each case of death. We set dominant race as the color of the boxes in the plot. The boxes along each column mark the 25th to 75th percentile of counts of deaths per zip code for each cause. The whiskers mark the highest and lowest count values considered to not be outliers. From this plot we notice heart disease accounts for the highest counts of deaths for all races. We added a filter to this boxplot which will plot according to data from zip codes within the chosen range of death counts.

knitr::include_graphics("../03Visualizations/Shiny_Screenshots/gettingdata1.png")

knitr::include_graphics("../03Visualizations/Shiny_Screenshots/plot1.png")

Histogram Tab

The histogram displayed is created by grouping zip codes of different median ages to bins with ranges of 5 years. The zip codes corresponding to the median ages assigned by each zip code have their count of deaths summed and displayed as the columns of the plot.

knitr::include_graphics("../03Visualizations/Shiny_Screenshots/gettingdata2.png")

knitr::include_graphics("../03Visualizations/Shiny_Screenshots/plot2.png")

Scatter Plot Tab

The scatter plot created has a point corresponding to the count of deaths of each cause per zip code. These points are organized along the x axis by their median age and placed along the y axis by their count of deaths. The color each point is assigned by the cause of death the count represents. From the plot we can make the observation that median age of zip codes are normally distributed about age. This can be noted by the larger count of deaths in the middle of the plot since most zip codes have middle aged median age zip codes.Less deaths occur in the highest a lowest median age zip codes. The increase in count of deaths around median age of 40 can be explained by the increased risk for heart disease seen in males over the age of 45. High numbers of over 45 year olf males may account for the rise in deaths.

knitr::include_graphics("../03Visualizations/Shiny_Screenshots/gettingdata3.png")

knitr::include_graphics("../03Visualizations/Shiny_Screenshots/plot3.png")

knitr::include_graphics("../03Visualizations/Shiny_Screenshots/plot3.1.png")

Crosstab Tab

The cross tab created has causes of death labled on the y-axis and dominant race in the x-axis. Each cell then displayed the sum of the count of deaths in the zip codes with a certain dominant race due to a certain cuase. In addition, before retrieving the data, users can define the ranges corresponding to a low, medium, and high KPI using the sliders in the data tab. The KPI we created was average deaths per zip code. This KPI takes the sum of the counts as displayed in the cells and divides that by the number of zip codes taken in to account in the sum of the counts. This definition of high, low and medium average deaths per zip codes is taken by the query sent to data.world. The query returns a column in the data defining whether a cause of death and dominant race combination has a high, low or medium average deaths per zip code. This parameter is then used to color the cells in the crosstab with its corresponding level of average deaths.

From this plot we notice heart disease accounted for more deaths per zip code for all races when compared to deaths due to cancer. This leads us to believe that genetic links to heart disease are less relevant as opposed to the health habits of all people regradless of race.

We also notice that only whites and american indian dominated zip codes suffered deaths due to injury in the same order of magnitude as their corresponding deaths due to heart diesease. The same cannot be said about the rest of the races.

knitr::include_graphics("../03Visualizations/Shiny_Screenshots/gettingdata4.png")

knitr::include_graphics("../03Visualizations/Shiny_Screenshots/plot4.png")

Bar Chart Tab

For our barchart, median age zip codes were grouped together. These groupings were then each divided by cause of death as seen in the y axis. The length of the bars account for the average death count per zip code for a certain cause of death in zip codes of a certain median age range. In addition a reference line was added to each median age grouping. This line indicates the average of the average deaths per zip codes in each grouping. The numbers labeled next to the bars correspond to the average of the average death count per zip code. From this plot we notice average deaths per zip code due to injury doubles when moving from zip codes from ages 60-70 to zip codes with median ages 70-80.

knitr::include_graphics("../03Visualizations/Shiny_Screenshots/gettingdata5.png")

knitr::include_graphics("../03Visualizations/Shiny_Screenshots/plot5.png")

knitr::include_graphics("../03Visualizations/Shiny_Screenshots/plot6.png")

knitr::include_graphics("../03Visualizations/Shiny_Screenshots/plot6.1.png")

knitr::include_graphics("../03Visualizations/Shiny_Screenshots/plot6.2.png")

Key for Causes of Death Abbreviations

Cause-of-death were coded using the Tenth Revision of the International Classification of Diseases codes (ICD-10). This is in the same data.world profile (@health) that we retrieved our data for the count of deaths by causes from.

SQL Query for Grouping and Joining data

Dominant Race Query and join

THIS WAS USED FOR CROSSTAB 1 IN OUR SHINY APP
Creating bins in dominantRace.csv

The following query is an example of how the census data was processed to define the dominant race in a zip code. The same process followed to define median income and median age in each zip code analyzed.

select ZCTA as ZipCode, CASE WHEN B02008_001 >= B02009_001 AND B02008_001 >= B02010_001 AND B02008_001 >= B02011_001 AND B02008_001 >= B02012_001 AND B02008_001 >= B02013_001 THEN “White” WHEN B02009_001 >= B02008_001 AND B02009_001 >= B02010_001 AND B02009_001 >= B02011_001 AND B02009_001 >= B02012_001 AND B02009_001 >= B02013_001 THEN “Black” WHEN B02010_001 >= B02008_001 AND B02010_001 >= B02009_001 AND B02010_001 >= B02011_001 AND B02010_001 >= B02012_001 AND B02010_001 >= B02013_001 THEN “American_Indian” WHEN B02011_001 >= B02008_001 AND B02011_001 >= B02009_001 AND B02011_001 >= B02010_001 AND B02011_001 >= B02012_001 AND B02011_001 >= B02013_001 THEN “Asian” WHEN B02012_001 >= B02008_001 AND B02012_001 >= B02009_001 AND B02012_001 >= B02010_001 AND B02012_001 >= B02011_001 AND B02012_001 >= B02013_001 THEN “Native_Hawaiian” WHEN B02013_001 >= B02008_001 AND B02013_001 >= B02009_001 AND B02013_001 >= B02010_001 AND B02013_001 >= B02011_001 AND B02013_001 >= B02012_001 THEN “Other” end AS Dominant from USA_ZCTA where B02008_001 is not null AND B02009_001 is not null AND B02010_001 is not null AND B02011_001 is not null AND B02012_001 is not null AND B02013_001 is not null

The rest of the queries that helped us create bins can be found at “../01Data/commands.sql”

LS0tDQp0aXRsZTogJzxjZW50ZXI+PGI+RmluYWwgUHJvamVjdDogQ2F1c2Ugb2YgRGVhdGggQW5hbHlzaXMgaW4gQ2FsaWZvcm5pYSBaaXAgQ29kZXMgPC9iPjwvY2VudGVyPicNCmF1dGhvcjogIjxjZW50ZXI+PGI+QW5hbmQgUGFudCwgQmFybmV5IFBlcmV6LCBMaW5hIExvcGV6LCBUb21teSBXaWxjemVrPC9iPjwvY2VudGVyPiINCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDoNCiAgICB0b2M6IHllcw0KICBodG1sX25vdGVib29rOg0KICAgIHRvYzogeWVzDQotLS0NCjxjZW50ZXI+IVtjYWxpZm9ybmlhXShjYWxpZm9ybmlhLnBuZyk8L2NlbnRlcj4NCg0KIyoqSW50cm9kdWN0aW9uKioNCk91ciBnb2FsIGZvciB0aGlzIHBvcmplY3Qgd2FzIHRvIGNyZWF0ZSBpbnRlcmVzdGluZyB2aXN1YWxpemF0aW9uIHNob3dpbmcgY29ycmVsYXRpb25zIGJldHdlZW4gY2F1c2VzIG9mIGRlYXRoIGFuZCB0aGUgZGVtb2dyYXBoaWMgdHJlbmRzIGluIHRoZSB6aXAgY29kZXMgb2YgQ2FsaWZvcm5pYS4gDQoNCkluIG9yZGVyIHRvIGRvIHNvIHdlIGFyZSBjbGVhbmluZyBkaXJ0eSBaaXAgY29kZSBkYXRhIGZyb20gdGhlIFVTIENlbnN1cyBhbmQgYXMgd2VsbCBhcyB6aXAgY29kZSBkYXRhIGNvcnJlc3BvbmRpbmcgdG8gY2F1c2Ugb2YgZGVhdGguIFRoZXNlIGRhdGEgc2V0cyBhcmUgYXZhaWxhYmxlIG9uIGRhdGEud29ybGQuIFRoZXNlIGRhdGEgc2V0cyBhcmUgam9pbmVkIHVzaW5nIFRhYmxlYXUgYW5kIFIsIHdpdGggd2hpY2ggd2UgY2FuIHByb2R1Y2UgdGhlIHZpc3VhbGl6YXRpb25zIHdlIHByZXNlbnQgaW4gdGhpcyBkb2N1bWVudC4NCg0KVGhlIGZvbGxvd2luZyBsaW5rcyByZWZlciB0byB0aGUgY2Vuc3VzIGRhdGEgdXNlZCBmb3Igb3V0IHZpc3VhbGl6YXRpb25zLg0KDQpNZWRpYW4gSW5jb21lIGRhdGEgd2FzIHRha2VuIGZyb20gdGhlIGZvbGxvd2luZyBsaW5rIHRvIHRoZSBVUyBDZW5zdXMgRGF0YSBpbiBkYXRhLndvcmxkOg0KaHR0cHM6Ly9kYXRhLndvcmxkL3VzY2Vuc3VzYnVyZWF1L2Fjcy0yMDE1LTUtZS1pbmNvbWUNCg0KTWVkaWFuIEFnZSBkYXRhIHdhcyB0YWtlbiBmcm9tIHRoZSBmb2xsb3dpbmcgbGluayB0byB0aGUgVVMgQ2Vuc3VzIERhdGEgaW4gZGF0YS53b3JsZDoNCmh0dHBzOi8vZGF0YS53b3JsZC91c2NlbnN1c2J1cmVhdS9hY3MtMjAxNS01LWUtYWdlc2V4DQoNCkRvbWluYW50IFJhY2UgZGF0YSB3YXMgdGFrZW4gZnJvbSB0aGUgZm9sbG93aW5nIGxpbmsgdG8gdGhlIFVTIENlbnN1cyBEYXRhIGluIGRhdGEud29ybGQ6DQpodHRwczovL2RhdGEud29ybGQvdXNjZW5zdXNidXJlYXUvYWNzLTIwMTUtNS1lLXJhY2UNCg0KIyoqUiBDb25maWd1cmF0aW9uKioNCkJlbG93IHdlIGRpc3BsYXkgb3VyIHNlc3Npb25JbmZvKCkuDQoNCmBgYHtyIHNlc3Npb25JbmZvfQ0Kc2Vzc2lvbkluZm8ocGFja2FnZT1OVUxMKQ0KYGBgDQoNCiMqKkRhdGEgU3VtbWFyeSoqDQpUaGUgZm9sbHdvaW5nIGhlYWRzIGFuZCBzdW1tYXJpZXMgZGVtb25zdHJhdGUgdGhlIGRhdGEgdGhhdCB3aWxsIGJlIGpvaW5lZCB2aWEgZGF0YS53b3JsZCBpbiBvdXIgcXVlcmllcyB3aGVuIHVzaW5nIHNoaW55LiBUaGlzIGRhdGEgd2lsbCBhbHNvIGJlIGpvaW5lZCBpbiB0YWJsZWF1IGZvciB0aGUgY29ycmVzcG9uZGluZyB2aXN1YWxpemF0aW9ucy4gIA0KDQpgYGB7ciBlY2hvPUZBTFNFfQ0Kc3VtbWFyeShkZikgDQpoZWFkKGRmKQ0KYGBgDQoNCmBgYHtyIGVjaG89RkFMU0V9DQpzdW1tYXJ5KGRlYXRocykgDQpoZWFkKGRlYXRocykNCmBgYA0KDQojKipQcm9jZXNzaW5nIHRoZSBEYXRhKioNClRoZSBjc3YgZmlsZXMgY29udGFpbmluZyBvdXIgZGF0YSBvZiBpbnRlcmVzdCB3ZXJlIHBhc3NlZCB0aHJvdWdoIGluZGl2aWR1YWwgRVRMIGZpbGVzIGZvciBjbGVhbmluZy4gSW4gdGhpcyBwcm9jZXNzIHNwYWNlcyBhcmUgaW5jbHVkZWQgYmV0d2VlbiB1cHBlciBhbmQgbG93ZXIgY2FzZWQgbGV0dGVycyBhbmQgYW1wZXJzYW5kcyBhcmUgY2hhbmdlZCB0byB0aGUgd29yZCAiYW5kIi5UaGVzZSBzdWJ0bGV0aWVzIGFtb25nIG90aGVycyBhcmUgZG9uZSB0byBlZmZlY3RpdmVseSB1cGxvYWQgdGhlIGRhdGEgZmlsZXMgdG8gZGF0YS53b3JsZC4gQmVjYXVzZSBvdXIgZGF0YSBkaWQgbm90IHJlcXVpcmUgbXVjaCAiY2xlYW5pbmciIG9yIHJlbmFtaW5nIG9mIGNvbHVtbnMsIHdlIGRpZCBub3QgbmVlZCB0byBpbmNsdWRlIGluIGRlcHRoIGNvZGUgaW4gdGhlIEVUTCBmaWxlLiBXZSB1c2VkIG1hbnkgImNvb2tpZS1jdXR0ZXIiIEVUTCBmaWxlcyB0byBjbGVhbiB0aGUgbWFueSBmaWxlcyB3ZSB1c2VkIGZvciBvdXIgam9pbnMuIFRoZXNlIGZpbGVzIGluY2x1ZGUgIkVUTF9tZWRpYW5fYWdlLlIsIEVUTF9kb21pbmFudF9yYWNlLlIsIEVUTF9tZWRpYW5faW5jb21lLlIsIEVUTF9leHBvcnQxLlIsIEVUTF9leHBvcnQyLlIsIGFuZCBFVExfZXhwb3J0My5SLiIgQmVsb3cgaXMgYSBzb3VyY2Ugb3IgbGluayB0byBvbmUgb2Ygb3VyIEVUTCBmaWxlcy4gDQoNCkJlbG93IGlzIGEgc291cmNlIG9mIG91ciBldGwgZmlsZSB1c2VkIHRvIGNsZWFuIG91ciBkb21pbmFudCByYWNlIGZpbGUsDQpgYGB7ciBlY2hvPUZBTFNFfQ0KIHNvdXJjZSgiLi4vMDFEYXRhL0VUTF9kb21pbmFudF9yYWNlLlIiKQ0KYGBgDQoNClRoZSBmb2xsb3dpbmcgc2NyZWVuIHNob3Qgc2hvd3Mgc29tZSBvZiB0aGUgY29kZSB1c2VkIHRvIGNsZWFuIHRoZSBkb21pbmFudCByYWNlIGZpbGUuDQpgYGB7ciwgb3V0LndpZHRoID0gIjQwMHB4In0NCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCIuLi8wMURhdGEvZG9taW5hbnRSYWNlLnBuZyIpDQpgYGANCg0KDQoNCg0KIyoqVGFibGVhdSBWaXN1YWxpemF0aW9ucyBTdGVwcyoqDQoNCiMjKipSZXRyaWV2aW5nIG91ciBEYXRhKioNCldlIHB1bGxlZCBpbiAzIGdyb3VwZWQgZGF0YSBzZXRzIGZyb20gb3VyIHByb2plY3QgdGhhdCBvcmlnaW5hdGVkIGZyb20gdGhlIFVTIENlbnN1cyAoTWVkaWFuX0luY29tZV9SYXcuY3N2LCBhbmQgTWVkaWFuX0FnZV9SYXcuY3N2KS4gSW4gYWRkaXRpb24sIHdlIGdyb3VwZWQgYSBzZXQgZnJvbSByYWNlIGRlb21ncmFwaGljcyBDZW5zdXMgZGF0YSB0byBjcmVhdGUgdGhlIGRvbWlhbmF0X3JhY2UuY3N2LiBJbiBvcmRlciB0byBjcmVhdGUgdGhpcyBmaWxlLCB3ZSBxdWVyaWVkIHRoZSBvcmdpbmFsIGNlbnN1cyBkYXRhIGluIGEgd2F5IHdlIGNvdWxkIGRlZmluZSB0aGUgZG9taWFuYW50IHJhY2UgaW4gZWFjaCB6aXAgY29kZS5BIG5ldyBjb2x1bW4gd2FzIGFkZGVkIHRvIHRoZSBkYXRhIHNldCBpbmRpY2F0aW5nIHRoZSBtb3N0IHJlcHJlc2VudGVkIHJhY2UgaW4gZWFjaCB6aXAgY29kZS4gV2UgdXNlZCB0aGUgZGF0YS53b3JsZCBjb25uZWN0b3IgdG8gcmV0cmlldmUgZXZlcnl0aGluZyBmcm9tIG91ciBmaW5hbCBwcm9qZWN0IHNpdGUgb24gZGF0YS53b3JsZC4gVGhpcyBpcyB3aGVyZSB3ZSBhbHNvIHB1bGxlZCB0aGUgQ2F1c2Ugb2YgRGVhdGggZGF0YSBzZXQuIFRoZXNlIGZpbGVzIHdlcmUgaW5uZXIgam9pbmVkIG9uIFpJUCBDb2RlIHRvIGFuYWx5emUgY2F1c2UgYW5kIGNvdW50IG9mIGRlYXRoIHRvIG1lZGlhbiBpbmNvbWUsIGRvbWluYW50IHJhY2UsIGFuZCBtZWRpYW4gYWdlIGluIGVhY2ggWklQIENvZGUuDQoNCmBgYHtyLCBvdXQud2lkdGggPSAiNDAwcHgifQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoIi4uLzAzVmlzdWFsaXphdGlvbnMvam9pbi5wbmciKQ0KYGBgDQoNCiMjKipCb3hwbG90IFZpc3VhbGl6YXRpb24gU3RlcHMqKg0KDQojIyMjKipTdGVwIDEgLSBCb3hwbG90IE92ZXJ2aWV3KioNCkluIG9yZGVyIHRvIGNyZWF0ZSBvdXIgYm94IHBsb3Qgd2Ugc2V0IGNhdXNlcyBvZiBkZWF0aCBhcyB0aGUgY29sdW1ucyB3aGljaCBjYW4gYmUgc2VlbiBhbG9uZyB0aGUgeC1heGlzIG9mIHRoZSBwbG90LiBUaGUgcm93IGFyZSBzZXQgYXMgdGhlIGNvdW50IG9mIGRlYXRocyBhcyBzZWVuIG9uIHRoZSB5LWF4aXMgb2YgdGhlIHBsb3QuIEVhY2ggemlwIGNvZGUgaGFzIGEgY29ycmVzcG9uZGluZyBwb2ludCBvbiB0aGUgYm94cGxvdCBmb3IgZWFjaCBjYXVzZSBvZiBkZWF0aC4gV2Ugc2V0IGRvbWluYW50IHJhY2UgYXMgdGhlIGNvbG9yIG9mIHRoZSBwb2ludHMgaW4gdGhlIHBsb3QuIFRoZXJlZm9yZSwgdGhlIGNvbG9yIG9mIGVhY2ggcG9pbnQgZGVwZW5kcyBvbiBlYWNoIHppcCBjb2RlJ3MgZG9taW5hbnQgcmFjZS4gVGhlIGJveGVzIGFsb25nIGVhY2ggY29sdW1uIG1hcmsgdGhlIDI1dGggdG8gNzV0aCBwZXJjZW50aWxlIG9mIGNvdW50cyBvZiBkZWF0aHMgcGVyIHppcCBjb2RlIGZvciBlYWNoIGNhdXNlLiBUaGUgd2hpc2tlcnMgbWFyayB0aGUgaGlnaGVzdCBhbmQgbG93ZXN0IGNvdW50IHZhbHVlcyBjb25zaWRlcmVkIHRvIG5vdCBiZSBvdXRsaWVycy4gDQoNCiMjIyMqKlN0ZXAgMiAtIEZpbHRlcioqDQpXZSBhZGRlZCBhIGZpbHRlciB0byB0aGlzIGJveHBsb3QgaW4gb3JkZXIgdG8gZGVmaW5lIHRoZSByYW5nZSBvZiB0aGUgbWVkaWFuIGluY29tZXMgb2YgdGhlIHppcGNvZGVzIGRpc3BseWVkLiANCg0KYGBge3IsIG91dC53aWR0aCA9ICI0MDBweCJ9DQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygiLi4vMDNWaXN1YWxpemF0aW9ucy9Cb3hwbG90MS5wbmciKQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoIi4uLzAzVmlzdWFsaXphdGlvbnMvQm94cGxvdDIucG5nIikNCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCIuLi8wM1Zpc3VhbGl6YXRpb25zL0JveHBsb3QzLnBuZyIpDQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygiLi4vMDNWaXN1YWxpemF0aW9ucy9Cb3hwbG90NC5wbmciKQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoIi4uLzAzVmlzdWFsaXphdGlvbnMvQm94cGxvdDUucG5nIikNCmBgYA0KDQoNCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCIuLi8wM1Zpc3VhbGl6YXRpb25zL1RhYmxlYXVfU2NyZWVuc2hvdHMvQm94cGxvdDMucG5nIikNCg0KPGNlbnRlcj4hW2luY29tZV0oaW5jb21lX2FnZS5wbmcpPC9jZW50ZXI+DQoNCiMjKipIaXN0b2dyYW0gVmlzdWFsaXphdGlvbiBTdGVwcyoqDQoNCiMjIyMqKlN0ZXAgMSAtIEhpc3RvZ3JhbSBPdmVydmlldyoqDQpGb3IgdGhpcyBwbG90IHdlIHNldCBvdXIgY29sdW1uIGFzIG1lZGlhbiBob3VzZWhvbGQgaW5jb21lIGFuZCBjb2x1bW5zIHRvIGNvdW50IG9mIHBlb3BsZSBpbiB0aGUgY29ycmVzcG9uZGluZyBpbmNvbWUuIFRoZXJlZm9yZSwgZWFjaCBiYXIgcmVwcmVzZW50cyB0aGUgY291bnQgb2YgcGVvcGxlIGxpdmluZyBpbiB6aXAgY29kZXMgYmlubmVkIHRvIGNvcnJlc3BvbmRpbmcgbWVkaWFuIGluY29tZXMuIEluIGFkZGl0aW9uLCBkb21pbmFudCByYWNlIHdhcyBhZGRlZCBhcyBhIGNvbG9yIHRvIHJlcHJlc2VudCB0aGUgY291bnQgb2YgcGVvcGxlIGluIHRoYXQgYmlubmVkIG1lZGlhbiBpbmNvbWUgb2YgemlwIGNvZGVzIG9mIGVhY2ggZG9taW5hbnQgcmFjZS4gDQoNCiMjIyMqKlN0ZXAgMiAtIEZpbHRlcioqDQpGb3IgdGhpcyBwbG90IHJhY2Ugd2FzIHNldCBhcyBhIGZpbHRlci4gVGhlIHVzZXIgY2FuIHRoZW4gZmlsdGVyIHdoaWNoIGRvbWluYW50IHJhY2UgemlwIGNvZGVzIHNob3VsZCBiZSBkaXNwbGF5ZWQgaW4gdGhlIGJpbm5lZCBwb3B1bGF0aW9uIGNvdW50Lg0KDQoNCmBgYHtyLCBvdXQud2lkdGggPSAiNDAwcHgifQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoIi4uLzAzVmlzdWFsaXphdGlvbnMvVGFibGVhdV9TY3JlZW5zaG90cy8yLnBuZyIpDQoNCmBgYA0KDQojIyoqU2NhdHRlciBQbG90IFZpc3VhbGl6YXRpb24gU3RlcHMqKg0KDQojIyMjKipTdGVwIDEgLVNjYXR0ZXIgUGxvdCBPdmVydmlldyoqDQpJbiBvcmRlciB0byBjcmVhdGUgb3VyIHNjYXR0ZXIgcGxvdCB3ZSBzZXQgb3VyIGNvbHVtbnMgYXMgb3VyIHppcCBjb2RlIG1lZGlhbiBhZ2UgYW5kIHRoZSByb3dzIGFzIHRoZSBjb3VudCBvZiBkZWF0aHMuIEVhY2ggcG9pbnQgcmVwcmVzZW50cyB0aGUgY291bnQgb2YgZGVhdGhzIGluIGEgcGFydGljdWxhciB6aXAgY29kZS4gQ29sb3Igd2FzIGFkZGVkIHRvIHRoZXNlIHBvaW50cyB0byByZXByZXNlbnQgdGhlIGRvbWluYW50IHJhY2UgaW4gZWFjaCB6aXAgY29kZS4gDQoNCiMjIyMqKlN0ZXAgMiAtUGFnZXMqKg0KUGFnZXMgd2VyZSBhZGRlZCB0byB0aGUgdmlzdWFsaXphdGlvbiB3aXRoIHJlc3BlY3QgdG8gY2F1c2Ugb2YgZGVhdGguIEVhY2ggcGFnZSB0aGVuIG9ubHkgc2hvd3MgdGhlIGNvdW50IG9mIGRlYXRocyBkdWUgdG8gYSBzcGVjaWZpYyBjYXVzZSBmb3IgZWFjaCB6aXAgY29kZS4NCg0KIyMjIyoqU3RlcCAzIC1TY2F0dGVyIFBsb3QgTWFwKioNCkJhc2VkIG9uIHRoaXMgZGF0YSBhIG1hcCB3YXMgY3JlYXRlZCBpbiBhIHNlcGFyYXRlIHNoZWV0LiBQb2ludHMgaW4gdGhlIHN0YXRlIG9mIENhbGlmb3JuaWEgY29ycmVzcG9uZCB0byB0aGUgemlwIGNvZGVzIHNhbXBsZWQuIFRoZSBzaXplIG9mIHRoZSBwb2ludHMgY29ycmVzcG9uZCB0byB0aGUgbWVkaWFuIGluY29tZSBvZiBlYWNoIHppcCBjb2RlLlRoZSBjb2xvciBvZiBlYWNoIHBvaW50IGNvcnJlc3BvbmRzIHRvIHRoZSBtb3N0IHJlcHJlc2VudGVkIHJhY2UgaW4gZWFjaCB6aXAgY29kZS4NCg0KIyMjIyoqU3RlcCA0IC1aaXAgQ29kZSBMaW5lcyBNYXAqKg0KSW4gYWRkaXRpb24sIGFub3RoZXIgbWFwIHdhcyByZXByb2R1Y2VkIGluIGEgZGlmZmVyZW50IHNoZWV0IGRpdmlkaW5nIHRoZSBzdGF0ZSBvZiBjYWxpZm9ybmlhIGJ5IHppcCBjb2RlIGxpbmVzLiBEZWF0aCBjb3VudCBpcyByZXByZXNlbnRlZCBhcyB0aGUgY29sb3Igb2YgdGhlIGFyZWEgb2YgZWFjaCB6aXAgY29kZS4gQSBmaWx0ZXIgd2FzIGNyZWF0ZWQgdG8gb25seSBkaXNwbGF5IHppcCBjb2RlcyB3aXRoIGEgdGhlIGNob3NlbiByYW5nZSBvZiBkZWF0aHMuIEZyb20gdGhpcyBtYXAgd2Ugbm90ZSB0aGF0IHRoZSB6aXAgY29kZSB3aXRoIG1vc3QgZGVhdGhzIGR1ZSB0byBjYW5jZXIgaXMgbG9jYXRlZCBpbiBOQVBBIHZhbGxleS4gVGhpcyBsb2NhdGlvbiBpcyBrbm93biBmb3IgbWFzcyBmYXJtaW5nLiBXZSB3b3VsZCBiZSBpbnRyZXN0ZWQgaW4ga25vd2luZyBpZiBwZXN0aWNpZGVzIHVzZWQgaW4gdGhlIGFyZWEgY291bGQgYWNjb3VudCBmb3IgdGhlIGhpZ2hlc3QgY2FuY2VyIHJhdGVzIHNlZW4gaW4gdGhlIHN0YXRlIG9mIENhbGlmb3JuaWEuDQoNCiMjIyMqKlN0ZXAgMyAtQWN0aW9ucyoqDQpCb3RoIG1hcHMgcHJvZHVjZWQgd2VyZSBzZXQgYXMgYSB0YXJnZXQgc2hlZXRzIHdoaWNoIGNhbiBmaWx0ZXIgdG8gb25seSBzaG93IHppcCBjb2RlcyBkaXNwbGF5ZWQgaW4gdGhlIGNob3NlbiBwYWdlIGluIHRoZSBzY2F0dGVyIHBsb3Qgc2hlZXQuIFRoZXJlZm9yZSwgb25seSB6aXAgY29kZXMgYWZmZWN0ZWQgYnkgYSBjZXJ0YWluIGNhdXNlIG9mIGRlYXRocyB3aWxsIGJlIGRpc3BsYXllZCBpbiB0aGUgbWFwIGlmIHRoZSBjb3JyZXNwb25kaW5nIGNhdXNlIGlzIHRoZSBzZWxlY3RlZCBwYWdlLg0KDQpgYGB7ciwgb3V0LndpZHRoID0gIjQwMHB4In0NCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCIuLi8wM1Zpc3VhbGl6YXRpb25zL1RhYmxlYXVfU2NyZWVuc2hvdHMvMy5wbmciKQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoIi4uLzAzVmlzdWFsaXphdGlvbnMvVGFibGVhdV9TY3JlZW5zaG90cy81LnBuZyIpDQoNCmBgYA0KDQojIyoqQ3Jvc3N0YWIgVmlzdWFsaXphdGlvbiBTdGVwcyoqDQoNCiMjIyMqKlN0ZXAgMSAtIENyb3NzdGFiIE92ZXJ2aWV3KioNCkluIG9yZGVyIHRvIGNyZWF0ZSBvdXIgY3Jvc3N0YWIgd2Ugc2V0IHJhY2UgYXMgb3VyIGNvbHVtbnMgYW5kIGNhdXNlIG9mIGRlYXRoIGFzIG91ciByb3dzLiBUZXh0IHRoZW4gd2FzIGFkZGVkIGluIHRoZSBjZWxscyBhcyBjb3VudCBvZiBkZWF0aHMgcGVydGFpbmluZyB0byB0aGUgY2VsbC4gRWFjaCBjZWxsIHRoZW4gY29udGFpbnMgdGhlIGNvdW50IG9mIGRlYXRocyBmb3IgemlwIGNvZGVzIHdpdGggYSBjZXJ0YWluIGRvbWluYW50IHJhY2UgZHVlIHRvIGEgY2VydGFpbiBjYXVzZS4gVGhlIGNvbG9yIG9mIHRoZSB0ZXh0IGFzIHNldCBhcyBvdXIgS1BJIHdoaWNoIGlzIGRlY3JpYmVkIGluIHRoZSBuZXh0IHN0ZXAuDQoNCiMjIyMqKlN0ZXAgMiAtIENhbGN1bGF0ZWQgZmllbGQ6IEF2ZXJhZ2UgZGVhdGhzIHBlciB6aXAgY29kZSoqDQpGb3Igb3VyIGtleSBwcmVmb3JtYW5jZSBpbmRpY2F0b3Igd2UgY2hvc2UgdG8gZGl2aWRlIHRoZSBjb3VudCBmb3VuZCBpbiB0aGUgY3Jvc3N0YWIgY2VsbHMgYnkgdGhlIG51bWJlciBvZiB6aXBjb2RlcyBhY2NvdW50aW5nIGZvciB0aGUgY291bnQuIFRoaXMgZ2l2ZSB0aGUgYXZlcmdlIGNvdW50IG9mIGRlYXRocyBkdWUgdG8gYSBjZXJ0YWluIGNhdXNlIHBlciB6aXAgY29kZSBvZiBhIGNlcnRhaW4gZG9taW5hbnQgcmFjZS4gVGhlIGNvbG9yIG9mIHRoZSB0ZXh0IGluIGVhY2ggY2VsbCBjb3JyZXNwb25kcyB0byB0aGUgYXZlcmdhZSBkZWF0aHMgcGVyIHppcCBjb2RlIGluIHRoYXQgY2VsbC4NCg0KYGBge3IsIG91dC53aWR0aCA9ICI0MDBweCJ9DQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygiLi4vMDNWaXN1YWxpemF0aW9ucy9UYWJsZWF1X1NjcmVlbnNob3RzLzYucG5nIikNCg0KYGBgDQoNCiMjKipCYXJjaGFydCBWaXN1YWxpemF0aW9uIFN0ZXBzKioNCg0KIyMjIyoqU3RlcCAxIC0gQmFyY2hhcnQgT3ZlcnZpZXcqKg0KV2UgY3JlYXRlZCBiYXJjaGFydHMgYmV0d2VlbiBtZWRpYW4gYWdlIChvbmUgYmx1ZSkgYW5kIGNhdXNlIG9mIGRlYXRoIChzZWNvbmQgYmx1ZSkgaW4gdGhlIGNvbHVtbnMgc2xvdC4gVGhpcyB0aGVuIGxpc3RzIGFsbCB0aGUgY2F1c2VzIG9mIGRlYXRoIGFuZCB3aXRoaW4gZWFjaCBjYXVzZSBvZiBkZWF0aCBsaXN0cyB0aGUgbWVkaWFuIGFnZSBiaW5zIHdlIGNyZWF0ZWQgICBUaGUgS1BJLSBhdmVyYWdlIGRlYXRocyBwZXIgemlwIGNvZGUgKGdyZWVuKSB3YXMgYWRkZWQgYXMgdGhlIHJvdyBvZiB0aGUgYmFyY2hhcnRzLiBXaXRoIHRoaXMgYXZlcmFnZSBjb3VudCB3ZSBjYW4gY29tcGFyZSB0aGUgYXZlcmFnZSBudW1iZXIgb2YgcGVvcGxlIGR5aW5nIHBlciB6aXAgY29kZSBvZiBhIGNlcnRhaW4gY2F1c2Ugb2YgZGVhdGggYWNyb3NzIHppcCBjb2RlcyBvZiBkaWZmZXJlbnQgbWVkaWFuIGFnZXMuIFRoaXMgd2FzIGRvbmUgY29zaWRlcmluZyB0aGF0IGNlcnRhaW4gbWVkaWFuIGluY29tZXMgd2VyZSBvdmVyIHJlcHJlc2VudGVkIGluIG91ciBkYXRhLiBUaGVyZWZvcmUgdGhlIGJhcnMgb2Ygb3VyIGJhcmNoYXJ0IHJlcHJlc2VudCB0aGUgYXZlcmFnZSBjb3VudCBvZiBkZWF0aHMgcGVyemlwIGNvZGUgZHVlIHRvIGEgY2VydGFpbiBjYXVzZSBpbiB6aXAgY29kZXMgb2YgYSBjZXJ0YWluIG1lZGlhbiBpbmNvbWUuDQoNCiMjIyMqKlN0ZXAgMiAtIENhbGN1bGF0ZWQgRmllbGQ6IEF2ZXJhZ2UgZGVhdGhzIHBlciB6aXAgY29kZSoqDQpBcyBtZW50aW9uZWQsIHRoZSBjYWxjdWxhdGVkIGZpZWxkIHVzZWQgd2FzIGF2ZXJhZ2UgZGVhdGhzIHBlciB6aXAgY29kZS4gVGhpcyB0YWtlcyB0aGUgY291bnQgb2YgZGVhdGhzIGFuZCBkaXZpZGVzIGl0IGJ5IHRoZSBudW1iZXIgb2YgemlwIGNvZGVzIHJlcHJlc2VudGVkLg0KDQojIyMjKipTdGVwIDMgLSBSZWZlcmVuY2UgTGluZSoqDQpUaGUgcGFyYW1ldGVyIHJlcHJlc2VudGVkIGJ5IHJlZmVyZW5jZSBsaW5lcyB0YWtlcyB0aGUgYXZlcmFnZSBvZiB0aGUgYXZlcmFnZXMgb2YgZGVhdGhzIHBlciB6aXAgY29kZSBhY3Jvc3MgZGlmZmVyZW50IG1lZGlhbiBpbmNvbWVzIGR1ZSB0byB0aGUgc2FtZSBjYXVzZSBvZiBkZWF0aC4gVGhlcmVmb3JlLCBvbmUgcmVmZXJlbmNlIGxpbmUgaXMgYXNzaWduZWQgdG8gZWFjaCBjYXVzZSBvZiBkZWF0aCB0byByZXByZXNlbnQgdGhpcyBwYXJhbWV0ZXIuDQoNCiMjIyMqKlN0ZXAgNCAtIFRhYmxlIENhbGN1bGF0aW9ucyoqDQpUaGUgdGFibGUgY2FsY3VsYXRpb24gdGFrZXMgdGhlIGNhbGN1bGF0ZWQgYXZlcmFnZSB1c2VkIGFzIHRoZSBwYXJhbWV0ZXIgZm9yIG91ciByZWZlcm5jZSBsaW5lIGFuZCBzdWJ0cmFjdHMgdGhpcyBudW1iZXIgZnJvbSB0aGUgYXZlcmFnZSBjb3VudHMgaW4gZWFjaCBiYXIocmVzdWx0aW5nIGluIGEgZGlmZmVyZW5jZSBmb3IgZWFjaCBtZWRpYW4gaW5jb21lKS4gVGhpcyBjYWxjdWxhdGlvbiBpcyByZWZlcmVkIHRvIGFzIHRoZSBkaWZmZXJlbmNlIGZyb20gdGhlIGF2ZXJhZ2UuDQoNCmBgYHtyLCBvdXQud2lkdGggPSAiNDAwcHgifQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoIi4uLzAzVmlzdWFsaXphdGlvbnMvVGFibGVhdV9TY3JlZW5zaG90cy83LnBuZyIpDQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygiLi4vMDNWaXN1YWxpemF0aW9ucy9UYWJsZWF1X1NjcmVlbnNob3RzLzgucG5nIikNCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCIuLi8wM1Zpc3VhbGl6YXRpb25zL1RhYmxlYXVfU2NyZWVuc2hvdHMvOS5wbmciKQ0KDQpgYGANCg0KDQojKipTaGlueSBWaXN1YWxpemF0aW9uIFN0ZXBzKioNCkxpbms6IGh0dHBzOi8vYW5hbmRwYW50LnNoaW55YXBwcy5pby9wcm9qZWN0X2ZpbmFsLw0KDQpUaGUgc2hpbnkgYXBwIGNyZWF0ZXMgcGxvdHMgdXNpbmcgcXVlcmllcyBzZXQgdG8gYnJpbmcgaW4gZGF0YSBvZiBpbnRlcmVzdCBmcm9tIGRhdGEud29ybGQuIEluIHRoZXNlIHF1ZXJpZXMgQ2Vuc3VzIGRhdGEgaXMgam9pbmVkIHRvIHRoZSBjYXVzZXMgb2YgZGVhdGggZmlsZXMuIFRoaXMgaXMgY3JlYXRlZCB3aXRoIGFuIGlubmVyIGpvaW4gb24gdGhlIHppcCBjb2RlIGluIGJvdGggZmlsZXMuIFRoZSBTUUwgdG8gam9pbiBpcyBmb3VuZCBpbiB0aGUgc2VydmVyIGNvZGUgZm9yIG91ciBzaGlueSBhcGxpY2F0aW9uLiANCg0KVGhlIHVzZXIgc2hvdWxkIGNsaWNrIG9uIHRoZSBnZXQgZGF0YSBidXR0b24uIFRoaXMgYnV0dG9uIHNlbmRzIGEgU1FMIHF1ZXJ5IHRvIGRhdGEud29ybGQgdG8gam9pbiBhbmQgYnJpbmcgaW4gIHRoZSBkYXRhIHNldCBtZW50aW9uZWQgYWJvdmUuIA0KDQpUaGUgcmV0dXJuZWQgZGF0YSBzZXQgd2lsbCBiZSB1c2VkIGJ5IGdncGxvdCBjb2RlIHRvIGNyZWF0ZSB0aGUgZGlmZmVyZW50IHZpc3VhbGl6YXRpb25zIHNob3duIGJlbG93LiANCg0KIyMjIyoqU3RlcCAxKioNCk5hdmlnYXRlIHRvIDAyIFNoaW55IGFuZCBvcGVuIFNlcnZlci5SDQoNCiMjIyMqKlN0ZXAgMioqDQpDbGljayBwdWJsaXNoLg0KDQojIyMjKipTdGVwIDMqKg0KQ2hvb3NlIGVpdGhlciBhZ2UsIHJhY2UsIG9yIGluY29tZSBpbiB0aGUgc2lkZWJhciBtZW51LiAgDQoNCiMjIyMqKlN0ZXAgNCoqDQpTZWxlY3QgZ2V0IGRhdGEuIFRoZSBiYXJjaGFydCB3aWxsIGJlIGNyZWF0ZWQuIFlvdSBjYW4gdmlldyB0aGUgYmFyY2hhcnQgYnkgY2xpY2tpbmcgYmFyY2hhcnQgdGFiLg0KDQoNCg0KIyoqU2hpbnkgVmlzdWFsaXphdGlvbnMqKg0KDQojIyMjKipTaGlueSAtIERhdGEgVGFiKioNClRoZSBpbWFnZSBiZWxvdyBzaG93cyB0aGUgZGF0YSB0YWIgcGFuZWwuIFRoaXMgaXMgZm91bmQgaW4gZXZlciB0YWIgaW4gb3VyIGFwcGxpY2F0aW9uLiBJdCBkaXNwbGF5cyB0aGUgZGF0YSB3ZSB1c2UgaW4gb3VyIHZpc3VhbGl6YXRpb24gaW4gYSB0YWJ1bGF0ZWQgZm9ybWF0LiBUaGlzIGRhdGEgaXMgdGhlIGRhdGEgd2UgcXVlcnkgZnJvbSBkYXRhLndvcmxkIHdoaWNoIGlzIHF1ZXJpZWQgdXBvbiBzZWxlY3RpbmcgdGhlIGdldCBkYXRhIGJ1dHRvbi4NCg0KIyMjIyoqIEJveHBsb3QgVGFiKioNCkluIG9yZGVyIHRvIGNyZWF0ZSBvdXIgYm94IHBsb3Qgd2Ugc2V0IGNhdXNlcyBvZiBkZWF0aCBhcyAgdGhlIHgtYXhpcyBvZiB0aGUgcGxvdC4gVGhlIHkgYXhpcyBpcyBzZXQgYXMgdGhlIGNvdW50IG9mIGRlYXRocy4gRWFjaCBzZXQgb2YgemlwIGNvZGUgZm9yIGVhY2ggZG9taW5hbnQgcmFjZSBoYXMgYSBjb3JyZXNwb25kaW5nIGJveCBhbmQgd2hpc2tlciBwbG90IGZvciBlYWNoIGNhc2Ugb2YgZGVhdGguIFdlIHNldCBkb21pbmFudCByYWNlIGFzIHRoZSBjb2xvciBvZiB0aGUgYm94ZXMgaW4gdGhlIHBsb3QuIFRoZSBib3hlcyBhbG9uZyBlYWNoIGNvbHVtbiBtYXJrIHRoZSAyNXRoIHRvIDc1dGggcGVyY2VudGlsZSBvZiBjb3VudHMgb2YgZGVhdGhzIHBlciB6aXAgY29kZSBmb3IgZWFjaCBjYXVzZS4gVGhlIHdoaXNrZXJzIG1hcmsgdGhlIGhpZ2hlc3QgYW5kIGxvd2VzdCBjb3VudCB2YWx1ZXMgY29uc2lkZXJlZCB0byBub3QgYmUgb3V0bGllcnMuIEZyb20gdGhpcyBwbG90IHdlIG5vdGljZSBoZWFydCBkaXNlYXNlIGFjY291bnRzIGZvciB0aGUgaGlnaGVzdCBjb3VudHMgb2YgZGVhdGhzIGZvciBhbGwgcmFjZXMuDQpXZSBhZGRlZCBhIGZpbHRlciB0byB0aGlzIGJveHBsb3Qgd2hpY2ggd2lsbCBwbG90IGFjY29yZGluZyB0byBkYXRhIGZyb20gemlwIGNvZGVzIHdpdGhpbiB0aGUgY2hvc2VuIHJhbmdlIG9mIGRlYXRoIGNvdW50cy4gDQoNCmBgYHtyLCBvdXQud2lkdGggPSAiNDAwcHgifQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoIi4uLzAzVmlzdWFsaXphdGlvbnMvU2hpbnlfU2NyZWVuc2hvdHMvZ2V0dGluZ2RhdGExLnBuZyIpDQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygiLi4vMDNWaXN1YWxpemF0aW9ucy9TaGlueV9TY3JlZW5zaG90cy9wbG90MS5wbmciKQ0KYGBgDQoNCiMjIyMqKkhpc3RvZ3JhbSBUYWIqKg0KVGhlIGhpc3RvZ3JhbSBkaXNwbGF5ZWQgaXMgY3JlYXRlZCBieSBncm91cGluZyB6aXAgY29kZXMgb2YgZGlmZmVyZW50IG1lZGlhbiBhZ2VzIHRvIGJpbnMgd2l0aCByYW5nZXMgb2YgNSB5ZWFycy4gVGhlIHppcCBjb2RlcyBjb3JyZXNwb25kaW5nIHRvIHRoZSBtZWRpYW4gYWdlcyBhc3NpZ25lZCBieSBlYWNoIHppcCBjb2RlIGhhdmUgdGhlaXIgY291bnQgb2YgZGVhdGhzIHN1bW1lZCBhbmQgZGlzcGxheWVkIGFzIHRoZSBjb2x1bW5zIG9mIHRoZSBwbG90Lg0KDQpgYGB7ciwgb3V0LndpZHRoID0gIjQwMHB4In0NCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCIuLi8wM1Zpc3VhbGl6YXRpb25zL1NoaW55X1NjcmVlbnNob3RzL2dldHRpbmdkYXRhMi5wbmciKQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoIi4uLzAzVmlzdWFsaXphdGlvbnMvU2hpbnlfU2NyZWVuc2hvdHMvcGxvdDIucG5nIikNCmBgYA0KDQojIyMjKipTY2F0dGVyIFBsb3QgVGFiKioNClRoZSBzY2F0dGVyIHBsb3QgY3JlYXRlZCBoYXMgYSBwb2ludCBjb3JyZXNwb25kaW5nIHRvIHRoZSBjb3VudCBvZiBkZWF0aHMgb2YgZWFjaCBjYXVzZSBwZXIgemlwIGNvZGUuIFRoZXNlIHBvaW50cyBhcmUgb3JnYW5pemVkIGFsb25nIHRoZSB4IGF4aXMgYnkgdGhlaXIgbWVkaWFuIGFnZSBhbmQgcGxhY2VkIGFsb25nIHRoZSB5IGF4aXMgYnkgdGhlaXIgY291bnQgb2YgZGVhdGhzLiBUaGUgY29sb3IgZWFjaCBwb2ludCBpcyBhc3NpZ25lZCBieSB0aGUgY2F1c2Ugb2YgZGVhdGggdGhlIGNvdW50IHJlcHJlc2VudHMuIEZyb20gdGhlIHBsb3Qgd2UgY2FuIG1ha2UgdGhlIG9ic2VydmF0aW9uIHRoYXQgbWVkaWFuIGFnZSBvZiB6aXAgY29kZXMgYXJlIG5vcm1hbGx5IGRpc3RyaWJ1dGVkIGFib3V0IGFnZS4gVGhpcyBjYW4gYmUgbm90ZWQgYnkgdGhlIGxhcmdlciBjb3VudCBvZiBkZWF0aHMgaW4gdGhlIG1pZGRsZSBvZiB0aGUgcGxvdCBzaW5jZSBtb3N0IHppcCBjb2RlcyBoYXZlIG1pZGRsZSBhZ2VkIG1lZGlhbiBhZ2UgemlwIGNvZGVzLkxlc3MgZGVhdGhzIG9jY3VyIGluIHRoZSBoaWdoZXN0IGEgbG93ZXN0IG1lZGlhbiBhZ2UgemlwIGNvZGVzLiANClRoZSBpbmNyZWFzZSBpbiBjb3VudCBvZiBkZWF0aHMgYXJvdW5kIG1lZGlhbiBhZ2Ugb2YgNDAgY2FuIGJlIGV4cGxhaW5lZCBieSB0aGUgaW5jcmVhc2VkIHJpc2sgZm9yIGhlYXJ0IGRpc2Vhc2Ugc2VlbiBpbiBtYWxlcyBvdmVyIHRoZSBhZ2Ugb2YgNDUuIEhpZ2ggbnVtYmVycyBvZiBvdmVyIDQ1IHllYXIgb2xmIG1hbGVzIG1heSBhY2NvdW50IGZvciB0aGUgcmlzZSBpbiBkZWF0aHMuDQoNCmBgYHtyLCBvdXQud2lkdGggPSAiNDAwcHgifQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoIi4uLzAzVmlzdWFsaXphdGlvbnMvU2hpbnlfU2NyZWVuc2hvdHMvZ2V0dGluZ2RhdGEzLnBuZyIpDQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygiLi4vMDNWaXN1YWxpemF0aW9ucy9TaGlueV9TY3JlZW5zaG90cy9wbG90My5wbmciKQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoIi4uLzAzVmlzdWFsaXphdGlvbnMvU2hpbnlfU2NyZWVuc2hvdHMvcGxvdDMuMS5wbmciKQ0KYGBgDQoNCiMjIyMqKkNyb3NzdGFiIFRhYioqDQpUaGUgY3Jvc3MgdGFiIGNyZWF0ZWQgaGFzIGNhdXNlcyBvZiBkZWF0aCBsYWJsZWQgb24gdGhlIHktYXhpcyBhbmQgZG9taW5hbnQgcmFjZSBpbiB0aGUgeC1heGlzLiBFYWNoIGNlbGwgdGhlbiBkaXNwbGF5ZWQgdGhlIHN1bSBvZiB0aGUgY291bnQgb2YgZGVhdGhzIGluIHRoZSB6aXAgY29kZXMgd2l0aCBhIGNlcnRhaW4gZG9taW5hbnQgcmFjZSBkdWUgdG8gYSBjZXJ0YWluIGN1YXNlLiBJbiBhZGRpdGlvbiwgYmVmb3JlIHJldHJpZXZpbmcgdGhlIGRhdGEsIHVzZXJzIGNhbiBkZWZpbmUgdGhlIHJhbmdlcyBjb3JyZXNwb25kaW5nIHRvIGEgbG93LCBtZWRpdW0sIGFuZCBoaWdoIEtQSSB1c2luZyB0aGUgc2xpZGVycyBpbiB0aGUgZGF0YSB0YWIuIFRoZSBLUEkgd2UgY3JlYXRlZCB3YXMgYXZlcmFnZSBkZWF0aHMgcGVyIHppcCBjb2RlLiBUaGlzIEtQSSB0YWtlcyB0aGUgc3VtIG9mIHRoZSBjb3VudHMgYXMgZGlzcGxheWVkIGluIHRoZSBjZWxscyBhbmQgZGl2aWRlcyB0aGF0IGJ5IHRoZSBudW1iZXIgb2YgemlwIGNvZGVzIHRha2VuIGluIHRvIGFjY291bnQgaW4gdGhlIHN1bSBvZiB0aGUgY291bnRzLiBUaGlzIGRlZmluaXRpb24gb2YgaGlnaCwgbG93IGFuZCBtZWRpdW0gYXZlcmFnZSBkZWF0aHMgcGVyIHppcCBjb2RlcyBpcyB0YWtlbiBieSB0aGUgcXVlcnkgc2VudCB0byBkYXRhLndvcmxkLiBUaGUgcXVlcnkgcmV0dXJucyBhIGNvbHVtbiBpbiB0aGUgZGF0YSBkZWZpbmluZyB3aGV0aGVyIGEgY2F1c2Ugb2YgZGVhdGggYW5kIGRvbWluYW50IHJhY2UgY29tYmluYXRpb24gaGFzIGEgaGlnaCwgbG93IG9yIG1lZGl1bSBhdmVyYWdlIGRlYXRocyBwZXIgemlwIGNvZGUuIFRoaXMgcGFyYW1ldGVyIGlzIHRoZW4gdXNlZCB0byBjb2xvciB0aGUgY2VsbHMgaW4gdGhlIGNyb3NzdGFiIHdpdGggaXRzIGNvcnJlc3BvbmRpbmcgbGV2ZWwgb2YgYXZlcmFnZSBkZWF0aHMuICANCg0KRnJvbSB0aGlzIHBsb3Qgd2Ugbm90aWNlIGhlYXJ0IGRpc2Vhc2UgYWNjb3VudGVkIGZvciBtb3JlIGRlYXRocyBwZXIgemlwIGNvZGUgZm9yIGFsbCByYWNlcyB3aGVuIGNvbXBhcmVkIHRvIGRlYXRocyBkdWUgdG8gY2FuY2VyLiBUaGlzIGxlYWRzIHVzIHRvIGJlbGlldmUgdGhhdCBnZW5ldGljIGxpbmtzIHRvIGhlYXJ0IGRpc2Vhc2UgYXJlIGxlc3MgcmVsZXZhbnQgYXMgb3Bwb3NlZCB0byB0aGUgaGVhbHRoIGhhYml0cyBvZiBhbGwgcGVvcGxlIHJlZ3JhZGxlc3Mgb2YgcmFjZS4NCg0KV2UgYWxzbyBub3RpY2UgdGhhdCBvbmx5IHdoaXRlcyBhbmQgYW1lcmljYW4gaW5kaWFuIGRvbWluYXRlZCB6aXAgY29kZXMgc3VmZmVyZWQgZGVhdGhzIGR1ZSB0byBpbmp1cnkgaW4gdGhlIHNhbWUgb3JkZXIgb2YgbWFnbml0dWRlIGFzIHRoZWlyIGNvcnJlc3BvbmRpbmcgZGVhdGhzIGR1ZSB0byBoZWFydCBkaWVzZWFzZS4gVGhlIHNhbWUgY2Fubm90IGJlIHNhaWQgYWJvdXQgdGhlIHJlc3Qgb2YgdGhlIHJhY2VzLg0KDQpgYGB7ciwgb3V0LndpZHRoID0gIjQwMHB4In0NCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCIuLi8wM1Zpc3VhbGl6YXRpb25zL1NoaW55X1NjcmVlbnNob3RzL2dldHRpbmdkYXRhNC5wbmciKQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoIi4uLzAzVmlzdWFsaXphdGlvbnMvU2hpbnlfU2NyZWVuc2hvdHMvcGxvdDQucG5nIikNCmBgYA0KDQojIyMjKipCYXIgQ2hhcnQgVGFiKioNCkZvciBvdXIgYmFyY2hhcnQsIG1lZGlhbiBhZ2UgemlwIGNvZGVzIHdlcmUgZ3JvdXBlZCB0b2dldGhlci4gVGhlc2UgZ3JvdXBpbmdzIHdlcmUgdGhlbiBlYWNoIGRpdmlkZWQgYnkgY2F1c2Ugb2YgZGVhdGggYXMgc2VlbiBpbiB0aGUgeSBheGlzLiBUaGUgbGVuZ3RoIG9mIHRoZSBiYXJzIGFjY291bnQgZm9yIHRoZSBhdmVyYWdlIGRlYXRoIGNvdW50IHBlciB6aXAgY29kZSBmb3IgYSBjZXJ0YWluIGNhdXNlIG9mIGRlYXRoIGluIHppcCBjb2RlcyBvZiBhIGNlcnRhaW4gbWVkaWFuIGFnZSByYW5nZS4gSW4gYWRkaXRpb24gYSByZWZlcmVuY2UgbGluZSB3YXMgYWRkZWQgdG8gZWFjaCBtZWRpYW4gYWdlIGdyb3VwaW5nLiBUaGlzIGxpbmUgaW5kaWNhdGVzIHRoZSBhdmVyYWdlIG9mIHRoZSBhdmVyYWdlIGRlYXRocyBwZXIgemlwIGNvZGVzIGluIGVhY2ggZ3JvdXBpbmcuIFRoZSBudW1iZXJzIGxhYmVsZWQgbmV4dCB0byB0aGUgYmFycyBjb3JyZXNwb25kIHRvIHRoZSBhdmVyYWdlIG9mIHRoZSBhdmVyYWdlIGRlYXRoIGNvdW50IHBlciB6aXAgY29kZS4gRnJvbSB0aGlzIHBsb3Qgd2Ugbm90aWNlIGF2ZXJhZ2UgZGVhdGhzIHBlciB6aXAgY29kZSBkdWUgdG8gaW5qdXJ5IGRvdWJsZXMgd2hlbiBtb3ZpbmcgZnJvbSB6aXAgY29kZXMgZnJvbSBhZ2VzIDYwLTcwIHRvIHppcCBjb2RlcyB3aXRoIG1lZGlhbiBhZ2VzIDcwLTgwLiAgDQoNCmBgYHtyLCBvdXQud2lkdGggPSAiNDAwcHgifQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoIi4uLzAzVmlzdWFsaXphdGlvbnMvU2hpbnlfU2NyZWVuc2hvdHMvZ2V0dGluZ2RhdGE1LnBuZyIpDQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygiLi4vMDNWaXN1YWxpemF0aW9ucy9TaGlueV9TY3JlZW5zaG90cy9wbG90NS5wbmciKQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoIi4uLzAzVmlzdWFsaXphdGlvbnMvU2hpbnlfU2NyZWVuc2hvdHMvcGxvdDYucG5nIikNCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCIuLi8wM1Zpc3VhbGl6YXRpb25zL1NoaW55X1NjcmVlbnNob3RzL3Bsb3Q2LjEucG5nIikNCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCIuLi8wM1Zpc3VhbGl6YXRpb25zL1NoaW55X1NjcmVlbnNob3RzL3Bsb3Q2LjIucG5nIikNCmBgYA0KDQojKipLZXkgZm9yIENhdXNlcyBvZiBEZWF0aCBBYmJyZXZpYXRpb25zKioNCkNhdXNlLW9mLWRlYXRoIHdlcmUgY29kZWQgdXNpbmcgdGhlIFRlbnRoIFJldmlzaW9uIG9mIHRoZSBJbnRlcm5hdGlvbmFsIENsYXNzaWZpY2F0aW9uIG9mIERpc2Vhc2VzIGNvZGVzIChJQ0QtMTApLiBUaGlzIGlzIGluIHRoZSBzYW1lIGRhdGEud29ybGQgcHJvZmlsZSAoQGhlYWx0aCkgdGhhdCB3ZSByZXRyaWV2ZWQgb3VyIGRhdGEgZm9yIHRoZSBjb3VudCBvZiBkZWF0aHMgYnkgY2F1c2VzIGZyb20uDQoNCiogSFREIC0gRGlzZWFzZXMgb2YgdGhlIEhlYXJ0DQoqIENBTiAtIE1hbGlnbmFudCBOZW9wbGFzbXMgKENhbmNlcnMpDQoqIFNUSyAtIENlcmVicm92YXNjdWxhciBEaXNlYXNlIChTdHJva2UpDQoqIENMRCAtIENocm9uaWMgTG93ZXIgUmVzcGlyYXRvcnkgRGlzZWFzZSAoQ0xSRCkNCiogSU5KIC0gVW5pbnRlbnRpb25hbCBJbmp1cmllcw0KKiBQTkYgLSBQbmV1bW9uaWEgYW5kIEluZmx1ZW56YQ0KKiBESUEgLSBEaWFiZXRlcyBNZWxsaXR1cw0KKiBBTFogLSBBbHpoZWltZXIncyBEaXNlYXNlDQoqIExJViAtIENocm9uaWMgTGl2ZXIgRGlzZWFzZSBhbmQgQ2lycmhvc2lzDQoqIFNVSSAtIEludGVudGlvbmFsIFNlbGYgSGFybSAoU3VpY2lkZSkNCiogSFlQIC0gRXNzZW50aWFsIEh5cGVydGVuc2lvbiBhbmQgSHlwZXJ0ZW5zaXZlIFJlbmFsIERpc2Vhc2UNCiogSE9NIC0gSG9taWNpZGUNCiogTkVQIC0gTmVwaHJpdGlzLCBOZXBocm90aWMgU3luZHJvbWUgYW5kIE5lcGhyb3Npcw0KKiBPVEggLSBBbGwgT3RoZXIgQ2F1c2VzIG9mIERlYXRoDQoNCiMqKlNRTCBRdWVyeSBmb3IgR3JvdXBpbmcgYW5kIEpvaW5pbmcgZGF0YSoqDQojIyMjKipEb21pbmFudCBSYWNlIFF1ZXJ5IGFuZCBqb2luKioNCg0KIyMjIyMqKlRISVMgV0FTIFVTRUQgRk9SIENST1NTVEFCIDEgSU4gT1VSIFNISU5ZIEFQUCoqDQoNCiMjIyMjQ3JlYXRpbmcgYmlucyBpbiBkb21pbmFudFJhY2UuY3N2DQoNClRoZSBmb2xsb3dpbmcgcXVlcnkgaXMgYW4gZXhhbXBsZSBvZiBob3cgdGhlIGNlbnN1cyBkYXRhIHdhcyBwcm9jZXNzZWQgdG8gZGVmaW5lIHRoZSBkb21pbmFudCByYWNlIGluIGEgemlwIGNvZGUuIFRoZSBzYW1lIHByb2Nlc3MgZm9sbG93ZWQgdG8gZGVmaW5lIG1lZGlhbiBpbmNvbWUgYW5kIG1lZGlhbiBhZ2UgaW4gZWFjaCB6aXAgY29kZSBhbmFseXplZC4gDQoNCnNlbGVjdCBaQ1RBIGFzIFppcENvZGUsDQogCUNBU0UNCiAJICAgIFdIRU4gQjAyMDA4XzAwMSA+PSAgQjAyMDA5XzAwMSBBTkQgQjAyMDA4XzAwMSA+PSAgQjAyMDEwXzAwMSBBTkQgQjAyMDA4XzAwMSA+PSAgQjAyMDExXzAwMSBBTkQgQjAyMDA4XzAwMSA+PSAgQjAyMDEyXzAwMSBBTkQgQjAyMDA4XzAwMSA+PSAgQjAyMDEzXzAwMSBUSEVOICJXaGl0ZSINCiAJCVdIRU4gQjAyMDA5XzAwMSA+PSAgQjAyMDA4XzAwMSBBTkQgQjAyMDA5XzAwMSA+PSAgQjAyMDEwXzAwMSBBTkQgQjAyMDA5XzAwMSA+PSAgQjAyMDExXzAwMSBBTkQgQjAyMDA5XzAwMSA+PSAgQjAyMDEyXzAwMSBBTkQgQjAyMDA5XzAwMSA+PSAgQjAyMDEzXzAwMSBUSEVOICJCbGFjayINCiAJCVdIRU4gQjAyMDEwXzAwMSA+PSAgQjAyMDA4XzAwMSBBTkQgQjAyMDEwXzAwMSA+PSAgQjAyMDA5XzAwMSBBTkQgQjAyMDEwXzAwMSA+PSAgQjAyMDExXzAwMSBBTkQgQjAyMDEwXzAwMSA+PSAgQjAyMDEyXzAwMSBBTkQgQjAyMDEwXzAwMSA+PSAgQjAyMDEzXzAwMSBUSEVOICJBbWVyaWNhbl9JbmRpYW4iDQogCQlXSEVOIEIwMjAxMV8wMDEgPj0gIEIwMjAwOF8wMDEgQU5EIEIwMjAxMV8wMDEgPj0gIEIwMjAwOV8wMDEgQU5EIEIwMjAxMV8wMDEgPj0gIEIwMjAxMF8wMDEgQU5EIEIwMjAxMV8wMDEgPj0gIEIwMjAxMl8wMDEgQU5EIEIwMjAxMV8wMDEgPj0gIEIwMjAxM18wMDEgVEhFTiAiQXNpYW4iDQogCQlXSEVOIEIwMjAxMl8wMDEgPj0gIEIwMjAwOF8wMDEgQU5EIEIwMjAxMl8wMDEgPj0gIEIwMjAwOV8wMDEgQU5EIEIwMjAxMl8wMDEgPj0gIEIwMjAxMF8wMDEgQU5EIEIwMjAxMl8wMDEgPj0gIEIwMjAxMV8wMDEgQU5EIEIwMjAxMl8wMDEgPj0gIEIwMjAxM18wMDEgVEhFTiAiTmF0aXZlX0hhd2FpaWFuIg0KIAkJV0hFTiBCMDIwMTNfMDAxID49ICBCMDIwMDhfMDAxIEFORCBCMDIwMTNfMDAxID49ICBCMDIwMDlfMDAxIEFORCBCMDIwMTNfMDAxID49ICBCMDIwMTBfMDAxIEFORCBCMDIwMTNfMDAxID49ICBCMDIwMTFfMDAxIEFORCBCMDIwMTNfMDAxID49ICBCMDIwMTJfMDAxIFRIRU4gIk90aGVyIg0KIAllbmQgQVMgRG9taW5hbnQNCiAJZnJvbSBVU0FfWkNUQQ0KIHdoZXJlIEIwMjAwOF8wMDEgaXMgbm90IG51bGwgQU5EIEIwMjAwOV8wMDEgaXMgbm90IG51bGwgQU5EIEIwMjAxMF8wMDEgaXMgbm90IG51bGwgQU5EIEIwMjAxMV8wMDEgaXMgbm90IG51bGwgQU5EIEIwMjAxMl8wMDEgaXMgbm90IG51bGwgQU5EIEIwMjAxM18wMDEgaXMgbm90IG51bGwNCiANCg0KVGhlIHJlc3Qgb2YgdGhlIHF1ZXJpZXMgdGhhdCBoZWxwZWQgdXMgY3JlYXRlIGJpbnMgY2FuIGJlIGZvdW5kIGF0ICIuLi8wMURhdGEvY29tbWFuZHMuc3FsIg0K